<template>
  <div class="text-block">
    <!-- 编辑模式 -->
    <div v-if="!previewMode" class="text-editor">
      <el-input
        ref="textareaRef"
        v-model="localContent.text"
        type="textarea"
        :rows="4"
        :placeholder="isDragOver ? '松开鼠标上传图片' : '请输入文本内容...支持Markdown语法，可直接粘贴或拖拽图片'"
        :class="{ 'drag-over': isDragOver }"
        @input="handleUpdate"
        @paste="handlePaste"
        @drop="handleDrop"
        @dragover="handleDragOver"
        @dragleave="handleDragLeave"
        resize="vertical"
      />
      
      <!-- 文本样式控制 -->
      <div class="text-controls">
        <el-row :gutter="12">
          <el-col :span="8">
            <el-form-item label="字体大小" size="small">
              <el-input-number
                v-model="localContent.fontSize"
                :min="12"
                :max="48"
                @change="handleUpdate"
                size="small"
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="文字颜色" size="small">
              <el-color-picker
                v-model="localContent.color"
                @change="handleUpdate"
                size="small"
              />
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item label="对齐方式" size="small">
              <el-select
                v-model="localContent.textAlign"
                @change="handleUpdate"
                size="small"
              >
                <el-option label="左对齐" value="left" />
                <el-option label="居中" value="center" />
                <el-option label="右对齐" value="right" />
                <el-option label="两端对齐" value="justify" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        
        <el-row :gutter="12">
          <el-col :span="6">
            <el-checkbox
              v-model="localContent.bold"
              @change="handleUpdate"
            >
              粗体
            </el-checkbox>
          </el-col>
          <el-col :span="6">
            <el-checkbox
              v-model="localContent.italic"
              @change="handleUpdate"
            >
              斜体
            </el-checkbox>
          </el-col>
          <el-col :span="6">
            <el-checkbox
              v-model="localContent.underline"
              @change="handleUpdate"
            >
              下划线
            </el-checkbox>
          </el-col>
          <el-col :span="6">
            <el-checkbox
              v-model="localContent.lineThrough"
              @change="handleUpdate"
            >
              删除线
            </el-checkbox>
          </el-col>
        </el-row>
      </div>
    </div>

    <!-- 预览模式 -->
    <div v-else class="text-preview" :style="textStyle">
      <div v-html="formattedText"></div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import apiService from '../../services/api.js'

// Props
const props = defineProps({
  block: {
    type: Object,
    required: true
  },
  previewMode: {
    type: Boolean,
    default: false
  }
})

// Emits
const emit = defineEmits(['update'])

// 本地内容状态
const localContent = ref({
  text: '请输入文本内容...',
  fontSize: 14,
  color: '#333333',
  textAlign: 'left',
  bold: false,
  italic: false,
  underline: false,
  lineThrough: false,
  ...props.block.content
})

// 文本框引用
const textareaRef = ref(null)

// 图片上传相关状态
const isDragOver = ref(false)

// 计算文本样式
const textStyle = computed(() => {
  const styles = {
    fontSize: `${localContent.value.fontSize}px`,
    color: localContent.value.color,
    textAlign: localContent.value.textAlign,
    lineHeight: '1.6'
  }
  
  if (localContent.value.bold) {
    styles.fontWeight = 'bold'
  }
  
  if (localContent.value.italic) {
    styles.fontStyle = 'italic'
  }
  
  const decorations = []
  if (localContent.value.underline) {
    decorations.push('underline')
  }
  if (localContent.value.lineThrough) {
    decorations.push('line-through')
  }
  if (decorations.length > 0) {
    styles.textDecoration = decorations.join(' ')
  }
  
  return styles
})

// 格式化文本（支持markdown语法）
const formattedText = computed(() => {
  let text = localContent.value.text
  const codeBlocks = []
  const inlineCodes = []
  
  // 首先提取并保护代码块，避免被其他规则影响（支持```和~~~两种语法）
  text = text.replace(/(```|~~~)([\s\S]*?)\1/g, function(match, delimiter, code) {
    const cleanCode = code.trim()
    const placeholder = `__CODE_BLOCK_${codeBlocks.length}__`
    codeBlocks.push(`<div style="background: #121212; border-radius: 5px; overflow: hidden; margin: 12px 0; padding: 0;"><div style="background: #121212; padding: 10px; display: flex; align-items: center;"><div style="width: 10px; height: 10px; border-radius: 5px; background: #E0443E; margin-left: 10px;"></div><div style="width: 10px; height: 10px; border-radius: 5px; background: #DEA123; margin-left: 5px;"></div><div style="width: 10px; height: 10px; border-radius: 5px; background: #1AAB29; margin-left: 5px;"></div></div><pre style="background: #121212; padding: 16px; margin: 0; overflow-x: auto; white-space: pre-wrap; border-top: 1px solid #333;"><code style="font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace; color: #ffffff; font-size: 14px; line-height: 1.45;">${cleanCode}</code></pre></div>`)
    return placeholder
  })
  
  // 提取并保护行内代码
  text = text.replace(/`([^`]+)`/g, function(match, code) {
    const placeholder = `__INLINE_CODE_${inlineCodes.length}__`
    inlineCodes.push(`<code style="background: #f1f3f4; padding: 2px 4px; border-radius: 3px; font-family: monospace;">${code}</code>`)
    return placeholder
  })
  
  // 标题语法 (# ## ### #### ##### ######)
  text = text.replace(/^######\s+(.+)$/gm, '<h6>$1</h6>')
  text = text.replace(/^#####\s+(.+)$/gm, '<h5>$1</h5>')
  text = text.replace(/^####\s+(.+)$/gm, '<h4>$1</h4>')
  text = text.replace(/^###\s+(.+)$/gm, '<h3>$1</h3>')
  text = text.replace(/^##\s+(.+)$/gm, '<h2>$1</h2>')
  text = text.replace(/^#\s+(.+)$/gm, '<h1>$1</h1>')
  
  // 粗体和斜体
  text = text.replace(/\*\*\*(.*?)\*\*\*/g, '<strong><em>$1</em></strong>')
  text = text.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
  text = text.replace(/\*(.*?)\*/g, '<em>$1</em>')
  
  // 删除线
  text = text.replace(/~~(.*?)~~/g, '<del>$1</del>')
  
  // 图片 ![alt](URL) 或 ![alt](URL "title")
  text = text.replace(/!\[([^\]]*)\]\(([^)\s]+)(?:\s+"([^"]*)")\)/g, '<img src="$2" alt="$1" title="$3" style="max-width: 100%; height: auto; border-radius: 8px; margin: 8px 0; box-shadow: 0 2px 8px rgba(0,0,0,0.1);" />')
  text = text.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '<img src="$2" alt="$1" style="max-width: 100%; height: auto; border-radius: 8px; margin: 8px 0; box-shadow: 0 2px 8px rgba(0,0,0,0.1);" />')
  
  // 链接 [文本](URL)
  text = text.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank" style="color: #007bff; text-decoration: none;">$1</a>')
  
  // 处理列表（需要更复杂的逻辑来正确包装连续的列表项）
  // 无序列表
  text = text.replace(/^[*+-]\s+(.+)$/gm, '::UL_ITEM::$1::UL_ITEM::')
  text = text.replace(/(::UL_ITEM::[\s\S]*?::UL_ITEM::)/g, function(match) {
    const items = match.replace(/::UL_ITEM::/g, '').split('::UL_ITEM::').filter(item => item.trim())
    return '<ul style="margin: 8px 0; padding-left: 20px;">' + items.map(item => `<li>${item}</li>`).join('') + '</ul>'
  })
  
  // 有序列表
  text = text.replace(/^\d+\.\s+(.+)$/gm, '::OL_ITEM::$1::OL_ITEM::')
  text = text.replace(/(::OL_ITEM::[\s\S]*?::OL_ITEM::)/g, function(match) {
    const items = match.replace(/::OL_ITEM::/g, '').split('::OL_ITEM::').filter(item => item.trim())
    return '<ol style="margin: 8px 0; padding-left: 20px;">' + items.map(item => `<li>${item}</li>`).join('') + '</ol>'
  })
  
  // 引用 - 支持多行引用
  text = text.replace(/(^>\s*.+$\n?)+/gm, function(match) {
    const lines = match.split('\n').filter(line => line.trim())
    const content = lines.map(line => line.replace(/^>\s*/, '')).join('<br>')
    return `<blockquote style="margin: 8px 0; padding: 8px 16px; border-left: 4px solid #3b82f6; background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%); font-style: normal; color: #000000; border-radius: 8px;">${content}</blockquote>`
  })
  
  // 水平分割线
  text = text.replace(/^---$/gm, '<hr style="border: none; border-top: 2px solid #eee; margin: 16px 0;">')
  
  // 表格支持（支持带分隔符和不带分隔符两种格式）
  // 格式1: 带分隔符的标准Markdown表格
  text = text.replace(/\|(.+)\|\n\|([\s\S]*?)\|\n((?:\|.+\|\n?)*)/g, function(match, header, separator, rows) {
    // 解析表头
    const headerCells = header.split('|').map(cell => cell.trim()).filter(cell => cell)
    const headerRow = '<tr>' + headerCells.map(cell => `<th style="padding: 8px 12px; border: 1px solid #ddd; background: #f8f9fa; font-weight: bold; text-align: left;">${cell}</th>`).join('') + '</tr>'
    
    // 解析表格行
    const tableRows = rows.trim().split('\n').map(row => {
      const cells = row.replace(/^\|/, '').replace(/\|$/, '').split('|').map(cell => cell.trim())
      return '<tr>' + cells.map(cell => `<td style="padding: 8px 12px; border: 1px solid #ddd;">${cell}</td>`).join('') + '</tr>'
    }).join('')
    
    return `<table style="border-collapse: collapse; width: 100%; margin: 12px 0; border: 1px solid #ddd;">${headerRow}${tableRows}</table>`
  })
  
  // 格式2: 简化表格（不需要分隔符行）
  text = text.replace(/((?:\|.+\|\n)+)/g, function(match) {
    const lines = match.trim().split('\n').filter(line => line.trim())
    if (lines.length < 2) return match // 至少需要2行才能构成表格
    
    // 检查是否已经被格式1处理过
    if (match.includes('<table')) return match
    
    // 第一行作为表头
    const headerLine = lines[0]
    const headerCells = headerLine.replace(/^\|/, '').replace(/\|$/, '').split('|').map(cell => cell.trim())
    const headerRow = '<tr>' + headerCells.map(cell => `<th style="padding: 8px 12px; border: 1px solid #ddd; background: #f8f9fa; font-weight: bold; text-align: left;">${cell}</th>`).join('') + '</tr>'
    
    // 其余行作为数据行
    const dataLines = lines.slice(1)
    const tableRows = dataLines.map(row => {
      const cells = row.replace(/^\|/, '').replace(/\|$/, '').split('|').map(cell => cell.trim())
      return '<tr>' + cells.map(cell => `<td style="padding: 8px 12px; border: 1px solid #ddd;">${cell}</td>`).join('') + '</tr>'
    }).join('')
    
    return `<table style="border-collapse: collapse; width: 100%; margin: 12px 0; border: 1px solid #ddd;">${headerRow}${tableRows}</table>`
  })
  
  // 换行
  text = text.replace(/\n/g, '<br>')
  
  // 恢复代码块
  codeBlocks.forEach((block, index) => {
    text = text.replace(`__CODE_BLOCK_${index}__`, block)
  })
  
  // 恢复行内代码
  inlineCodes.forEach((code, index) => {
    text = text.replace(`__INLINE_CODE_${index}__`, code)
  })
  
  return text
})

/**
 * 处理内容更新
 */
const handleUpdate = () => {
  // 智能检测图片语法
  detectImageSyntax()
  
  emit('update', {
    content: { ...localContent.value }
  })
}

/**
 * 智能检测图片语法
 */
const detectImageSyntax = () => {
  const textarea = textareaRef.value?.textarea || textareaRef.value
  if (!textarea) return
  
  const cursorPosition = textarea.selectionStart
  const textBeforeCursor = localContent.value.text.substring(0, cursorPosition)
  
  // 检测是否刚输入了 ![xxx](img)
  const imagePattern = /!\[([^\]]*)\]\(img\)$/
  const match = textBeforeCursor.match(imagePattern)
  
  if (match) {
    const altText = match[1] || '图片'
    // 移除刚输入的 img 部分
    const beforeMatch = textBeforeCursor.substring(0, match.index)
    const afterCursor = localContent.value.text.substring(cursorPosition)
    
    // 创建一个隐藏的文件输入元素
    const fileInput = document.createElement('input')
    fileInput.type = 'file'
    fileInput.accept = 'image/*'
    fileInput.style.display = 'none'
    
    fileInput.onchange = async (event) => {
      const file = event.target.files?.[0]
      if (file && beforeImageUpload(file)) {
        try {
          // 显示上传占位符
          const placeholder = `![${altText}](上传中...)`
          localContent.value.text = beforeMatch + placeholder + afterCursor
          
          // 上传图片
          const formData = new FormData()
          formData.append('image', file)
          const response = await apiService.items.uploadImage(formData)
          
          // 替换占位符为实际URL
          const finalMarkdown = `![${altText}](${response.data.url})`
          localContent.value.text = localContent.value.text.replace(placeholder, finalMarkdown)
          
          ElMessage.success('图片上传成功')
          
          // 触发更新
          emit('update', {
            content: { ...localContent.value }
          })
          
          // 设置光标位置
          await nextTick()
          setTimeout(() => {
            const newPosition = beforeMatch.length + finalMarkdown.length
            textarea.setSelectionRange(newPosition, newPosition)
            textarea.focus()
          }, 0)
        } catch (error) {
          console.error('图片上传失败:', error)
          ElMessage.error('图片上传失败，请重试')
          // 恢复原始文本
          localContent.value.text = beforeMatch + `![${altText}](img)` + afterCursor
        }
      }
      // 清理文件输入元素
      document.body.removeChild(fileInput)
    }
    
    // 添加到DOM并触发点击
    document.body.appendChild(fileInput)
    fileInput.click()
  }
}

/**
 * 处理粘贴事件
 */
const handlePaste = (event) => {
  const items = event.clipboardData?.items
  if (!items) return

  for (let i = 0; i < items.length; i++) {
    const item = items[i]
    if (item.type.indexOf('image') !== -1) {
      event.preventDefault()
      const file = item.getAsFile()
      if (file) {
        handleImageFile(file)
      }
      break
    }
  }
}

/**
 * 处理拖拽悬停事件
 */
const handleDragOver = (event) => {
  event.preventDefault()
  isDragOver.value = true
}

/**
 * 处理拖拽离开事件
 */
const handleDragLeave = (event) => {
  event.preventDefault()
  isDragOver.value = false
}

/**
 * 处理拖拽放置事件
 */
const handleDrop = (event) => {
  event.preventDefault()
  isDragOver.value = false
  
  const files = event.dataTransfer?.files
  if (!files || files.length === 0) return
  
  for (let i = 0; i < files.length; i++) {
    const file = files[i]
    if (file.type.startsWith('image/')) {
      handleImageFile(file)
      break // 只处理第一个图片文件
    }
  }
}

/**
 * 图片上传前验证
 */
const beforeImageUpload = (file) => {
  const isImage = file.type.startsWith('image/')
  const isLt5M = file.size / 1024 / 1024 < 5

  if (!isImage) {
    ElMessage.error('只能上传图片文件！')
    return false
  }
  if (!isLt5M) {
    ElMessage.error('图片大小不能超过 5MB！')
    return false
  }
  return true
}

/**
 * 处理图片文件上传
 */
const handleImageFile = async (file) => {
  // 验证文件类型和大小
  const validTypes = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif', 'image/svg+xml', 'image/webp']
  if (!validTypes.includes(file.type)) {
    ElMessage.error('图片格式不正确！支持 PNG、JPG、GIF、SVG、WebP 格式')
    return
  }
  
  if (file.size > 5 * 1024 * 1024) {
    ElMessage.error('图片大小不能超过 5MB!')
    return
  }
  
  // 生成唯一的上传ID
  const uploadId = Date.now() + Math.random().toString(36).substr(2, 9)
  const placeholder = `![上传中...](uploading-${uploadId})`
  
  // 在光标位置插入占位符
  insertTextAtCursor(placeholder)
  
  try {
    // 创建FormData
    const formData = new FormData()
    formData.append('image', file)
    formData.append('alt', '富文本编辑器图片')
    formData.append('caption', '')
    
    // 上传图片
    const response = await apiService.items.uploadImage(formData)
    
    if (response && response.data && response.data.url) {
      // 替换占位符为实际图片URL
      const imageMarkdown = `![图片](${response.data.url})`
      localContent.value.text = localContent.value.text.replace(placeholder, imageMarkdown)
      handleUpdate()
      ElMessage.success('图片上传成功')
    } else {
      throw new Error('上传响应格式错误')
    }
  } catch (error) {
    console.error('图片上传失败:', error)
    ElMessage.error('图片上传失败，请重试')
    // 移除占位符
    localContent.value.text = localContent.value.text.replace(/!\[上传中\.\.\.\]\(uploading-[^)]+\)/g, '')
    handleUpdate()
  }
}

/**
 * 在光标位置插入文本
 */
const insertTextAtCursor = (text) => {
  const textarea = textareaRef.value?.$refs?.textarea || textareaRef.value?.textarea
  if (!textarea) {
    // 如果无法获取textarea引用，直接添加到末尾
    localContent.value.text += '\n' + text
    handleUpdate()
    return
  }
  
  const start = textarea.selectionStart
  const end = textarea.selectionEnd
  const currentText = localContent.value.text
  
  // 在光标位置插入文本
  const newText = currentText.substring(0, start) + text + currentText.substring(end)
  localContent.value.text = newText
  handleUpdate()
  
  // 恢复光标位置
  nextTick(() => {
    const newCursorPos = start + text.length
    textarea.setSelectionRange(newCursorPos, newCursorPos)
    textarea.focus()
  })
}

// 监听 props 变化
watch(
  () => props.block.content,
  (newContent) => {
    localContent.value = {
      ...localContent.value,
      ...newContent
    }
  },
  { deep: true }
)
</script>

<style scoped>
.text-block {
  width: 100%;
}

.text-editor {
  width: 100%;
}

/* 拖拽样式 */
.text-editor :deep(.el-textarea__inner) {
  transition: all 0.3s ease;
}

.text-editor :deep(.el-textarea__inner:focus) {
  border-color: #409eff;
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
}

.text-editor :deep(.el-textarea__inner::placeholder) {
  color: #a8abb2;
}

.text-editor :deep(.drag-over .el-textarea__inner) {
  border-color: #67c23a !important;
  background-color: #f0f9ff !important;
  box-shadow: 0 0 0 2px rgba(103, 194, 58, 0.2) !important;
}

.text-controls {
  margin-top: 16px;
  padding: 16px;
  background: #f8f9fa;
  border-radius: 6px;
  border: 1px solid #e9ecef;
}

.text-controls .el-form-item {
  margin-bottom: 12px;
}

.text-controls .el-form-item:last-child {
  margin-bottom: 0;
}

.text-preview {
  min-height: 40px;
  word-wrap: break-word;
  white-space: pre-wrap;
}

.text-preview:empty::before {
  content: '空文本块';
  color: #999;
  font-style: italic;
}

/* Markdown样式 */
.text-preview :deep(h1) {
  font-size: 2em;
  font-weight: bold;
  margin: 16px 0 12px 0;
  color: #333;
  border-bottom: 2px solid #eee;
  padding-bottom: 8px;
}

.text-preview :deep(h2) {
  font-size: 1.75em;
  font-weight: bold;
  margin: 14px 0 10px 0;
  color: #333;
  border-bottom: 1px solid #eee;
  padding-bottom: 6px;
}

.text-preview :deep(h3) {
  font-size: 1.5em;
  font-weight: bold;
  margin: 12px 0 8px 0;
  color: #333;
}

.text-preview :deep(h4) {
  font-size: 1.25em;
  font-weight: bold;
  margin: 10px 0 6px 0;
  color: #333;
}

.text-preview :deep(h5) {
  font-size: 1.1em;
  font-weight: bold;
  margin: 8px 0 4px 0;
  color: #333;
}

.text-preview :deep(h6) {
  font-size: 1em;
  font-weight: bold;
  margin: 6px 0 2px 0;
  color: #666;
}

.text-preview :deep(code) {
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  font-size: 0.9em;
}

.text-preview :deep(pre) {
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  font-size: 0.9em;
  line-height: 1.4;
}

.text-preview :deep(blockquote) {
  margin: 12px 0;
  padding: 16px 20px;
  border-left: 5px solid #3b82f6;
  background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
  border-radius: 8px;
  font-style: normal;
  color: #000000;
  box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2);
  position: relative;
}

.text-preview :deep(blockquote::before) {
  content: '💡';
  font-size: 1.5em;
  color: #3b82f6;
  position: absolute;
  top: 12px;
  right: 16px;
  opacity: 0.6;
}

.text-preview :deep(ul), .text-preview :deep(ol) {
  margin: 8px 0;
  padding-left: 24px;
}

.text-preview :deep(li) {
  margin: 4px 0;
  line-height: 1.5;
}

.text-preview :deep(a) {
  color: #007bff;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-bottom-color 0.2s;
}

.text-preview :deep(a:hover) {
  border-bottom-color: #007bff;
}

.text-preview :deep(del) {
  color: #999;
  text-decoration: line-through;
}

.text-preview :deep(hr) {
  border: none;
  border-top: 2px solid #eee;
  margin: 20px 0;
}

.text-preview :deep(table) {
  border-collapse: collapse;
  width: 100%;
  margin: 12px 0;
  border: 1px solid #ddd;
  border-radius: 6px;
  overflow: hidden;
}

.text-preview :deep(th) {
  padding: 12px;
  border: 1px solid #ddd;
  background: #f8f9fa;
  font-weight: bold;
  text-align: left;
  color: #333;
}

.text-preview :deep(td) {
  padding: 12px;
  border: 1px solid #ddd;
  vertical-align: top;
}

.text-preview :deep(tr:nth-child(even)) {
  background: #f9f9f9;
}

.text-preview :deep(tr:hover) {
  background: #f0f8ff;
  transition: background-color 0.2s;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .text-controls .el-col {
    margin-bottom: 12px;
  }
  
  .text-controls .el-row {
    margin: 0;
  }
}
</style>